<?php

namespace Org\Util;

ini_set('date.timezone', 'Asia/Shanghai');

use Org\Util;

/**
 * Description of WeiXin
 *
 * @author Myron
 */
class WeiXin {

    
    public $_appid = null;
    public $_appsecret =null;

    //初始化
    function __construct() { //初始化对象，将初始化值放在括号内
        $this->_appid = C('WX_APPID');
        $this->_appsecret = C('WX_APPSECRET');
        Vendor("WxPay.lib.WxPay#Api");
        Vendor("WxPay.lib.WxPay#Data");        
        Vendor("WxPay.lib.WxPay#Config"); //正式环境
        Vendor("WxPay.lib.WxPay#Exception");  
        define('WX_APPID', C("WX_APPID"));
        define('WX_APPSECRET', C("WX_APPSECRET"));
        define('WX_MCHID', C("WX_MCHID"));
        define('WX_KEY', C("WX_KEY")); 
    }

    //初始化 
    /*
     * 微信支付页面使用的功能 
     */

    /**
     * 
     * 获取jsapi支付的参数
     * @param $type 微信支付类型 订单支付传入 order ，充值支付传入 recharge
     * @param $openId 微信openid
     * @param $out_trade_no 微信openid
     * @param $total_fee 微信openid
     * @param $Goods_tag 微信openid
     * @param $body 微信openid 
     * @param $attach 微信openid 
     * 
     * @return 返回生成后的js文件
     */
    public function getWxPayJsApiParameters($type = "", $openId = null, $out_trade_no = null, $total_fee = null, $Goods_tag = "", $body = "", $attach = "") {
        
        

        //①、获取用户openid  
        $wxopenId = $openId;
        //②、统一下单
        $input = new \WxPayUnifiedOrder(); 
        
        $input->SetBody($body);
        $input->SetAttach($attach);
        $input->SetOut_trade_no($out_trade_no);
        $input->SetTotal_fee($total_fee);
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetGoods_tag($Goods_tag);
        if ($type == "order") {
            $input->SetNotify_url("http://" . $_SERVER['HTTP_HOST'] . "/index.php/Home/WeixinNotify/Notify");
        }
        if ($type == "recharge") {
            $input->SetNotify_url("http://" . $_SERVER['HTTP_HOST'] . "/index.php/Home/WeixinNotify/NotifyRecharge");
        }
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($openId);

        $order = \WxPayApi::unifiedOrder($input);

        $jsApiParameters = $this->GetJsApiParameters($order);
        return $jsApiParameters;
    }

    /**
     * 
     * 获取jsapi支付的参数
     * @param array $UnifiedOrderResult 统一支付接口返回的数据
     * @throws WxPayException
     * 
     * @return json数据，可直接填入js函数作为参数
     */
    public function GetJsApiParameters($UnifiedOrderResult) {
        if (!array_key_exists("appid", $UnifiedOrderResult) || !array_key_exists("prepay_id", $UnifiedOrderResult) || $UnifiedOrderResult['prepay_id'] == "") {
            throw new \WxPayException("参数错误");
        }
        $jsapi = new \WxPayJsApiPay();
        $jsapi->SetAppid($UnifiedOrderResult["appid"]);
        $timeStamp = time();
        $jsapi->SetTimeStamp("$timeStamp");
        $jsapi->SetNonceStr(\WxPayApi::getNonceStr());
        $jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);
        $jsapi->SetSignType("MD5");
        $jsapi->SetPaySign($jsapi->MakeSign());
        $parameters = json_encode($jsapi->GetValues());
        return $parameters;
    }

    /*     * ****************************
     * 下面是微信分享页面使用的功能功能
     */

    //获取分享页面的签名
    public function getSignPackage() {
        $jsapiTicket = $this->getJsApiTicket();
        // 注意 URL 一定要动态获取，不能 hardcode.
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        $timestamp = time();
        $nonceStr = $this->createNonceStr();

        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";

        $signature = sha1($string);

        $signPackage = array(
            "appId" => $this->_appid,
            "nonceStr" => $nonceStr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $signature,
            "rawString" => $string,
            'wwwroot' => 'http://' . $_SERVER[HTTP_HOST]
        );

        return $signPackage;
    }
    //
    /*public function getSubscribeStatus($openid){
        $token=$this->getAccessToken();
        $url="https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$token."&openid=".$openid."&lang=zh_CN";
        $subinfo=$this->https_request($url);
        $status=json_decode($subinfo);
        $subcribe=$status->subscribe;
        if($subcribe==1){
            return true;
        }else{
            return false;
        }
    }*/
    public function getSubscribeStatus($openid){
        $token=$this->getAccessToken();
        $url="https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$token."&openid=".$openid."&lang=zh_CN";
        $subinfo=$this->https_request($url);
        $status=json_decode($subinfo);
        if($status->errcode === 40001){
            //token过期
            $this->getAccessToken(TRUE);
            return 40001;
        }else{
            $subcribe=$status->subscribe;
            if($subcribe==1){
                return true;
            }else{
                return false;
            }
        }
    }
    private function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    //获取access_token 有效期7200秒
    function getAccessToken($force = FALSE) {
        
        //文件存储的方式
//        $data = json_decode(file_get_contents("access_token.json"));  
//        if ($data->expire_time < time() || is_null($data->expire_time) || $force == TRUE) {
//            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->_appid . "&secret=" . $this->_appsecret . "";
//            $res = json_decode($this->httpGet($url));
//            $access_token = $res->access_token;
//            if ($access_token) {
//                $data->expire_time = time() + 7000;
//                $data->access_token = $access_token;
//                $fp = fopen("access_token.json", "w");
//                fwrite($fp, json_encode($data));
//                fclose($fp);              
//            }
//        } else {
//            $access_token = $data->access_token;
//        }
//        return $access_token;
        
       
        //改进成redis 缓存
        $data = S("access_token");   
        if ($data['expire_time'] < time() || is_null($data['expire_time']) || $force == TRUE) {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->_appid . "&secret=" . $this->_appsecret . "";
            $res = json_decode($this->httpGet($url));
            $access_token = $res->access_token;
            if ($access_token) {
                $data['expire_time'] = time() + 7000;
                $data['access_token'] = $access_token; 
                S("access_token",$data);
            }
        } else {
            $access_token = $data['access_token'];
        }
        return $access_token;
    }

    //获取JsApiTicket
    function getJsApiTicket() { 
        
        //文件存储方式
//        $data = json_decode(file_get_contents("jsapi_ticket.json"));         
//        if ($data->expire_time < time()|| is_null($data->expire_time) ) {
//            $accessToken = $this->getAccessToken();
//            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&type=jsapi";
//            $res = json_decode($this->httpGet($url));
//            $ticket = $res->ticket;
//            if ($ticket) {
//                $data->expire_time = time() + 7000;
//                $data->jsapi_ticket = $ticket;
//                $fp = fopen("jsapi_ticket.json", "w");
//                fwrite($fp, json_encode($data));
//                fclose($fp);
//              
//            }
//        } else {
//            $ticket = $data->jsapi_ticket;
//        }
//        return $ticket;
        
         
        $data = S("jsapi_ticket"); 
        if ($data['expire_time'] < time()|| is_null($data['expire_time'])) {
            $accessToken = $this->getAccessToken();
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&type=jsapi";
            $res = json_decode($this->httpGet($url));
            $ticket = $res->ticket;
            if ($ticket) {
                $data['expire_time'] = time() + 7000;
                $data['jsapi_ticket'] = $ticket;
                S("jsapi_ticket",$data);
            }
        } else {
            $ticket =$data['jsapi_ticket'];
        }
        return $ticket;
    }

    /*
     * 微信发送消息功能
     */

    public function sendWxMessages($templateid, $Data, $touser, $jumpurl = "") {
        $HttpTools = new HttpTools();
        $body['template_id'] = $templateid;
        $body['url'] = $jumpurl;
        $body['topcolor'] = "#FF0000";
        $body['data'] = $Data;
        $body['touser'] = $touser;
        $ACCESSTOKEN = $this->getAccessToken();
        $result = $HttpTools->POST_JSON("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$ACCESSTOKEN", $body);
//        \Think\Log::record(json_encode($ACCESSTOKEN));
//        \Think\Log::record(json_encode($body));
//        \Think\Log::record(json_encode($result));
        return $result;
    }

    //http工具
    function https_request($url, $data = null) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }

    private function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        // 为保证第三方服务器与微信服务器之间数据传输的安全性，所有微信接口采用https方式调用，必须使用下面2行代码打开ssl安全校验。
        // 如果在部署过程中代码在此处验证失败，请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

}
